#define _CRT_SECURE_NO_WARNINGS
#include"Hash_Map.h"

//void initiliaze_table(HashMap* hm)
//{
//	assert(hm);
//	for (int i = 0; i < hm->table_size; i++)
//	{
//		hm->table[i].key = NULL;
//		hm->table[i].value = NULL;
//		hm->table[i].next = NULL;
//	}
//}

HashMap* initialization(int ts)
{
	int table_size = DEFAULT_TABLE_SIZE;
	if (ts > DEFAULT_TABLE_SIZE)
		table_size = ts;
	HashMap* newmap = (HashMap*)malloc(sizeof(HashMap));
	if (newmap == NULL)
	{
		perror("Creat Map");
		exit(-1);
	}
	HashMap* hashmap = newmap;
	hashmap->table_size = table_size;
	ListNode* newtable= (ListNode*)malloc(sizeof(ListNode) * (hashmap->table_size));
	if (newtable == NULL)
	{
		perror("Creat Table");
		exit(-1);
	}
	hashmap->table = newtable;
	//initiliaze_table(hashmap);
	memset(hashmap->table, 0, sizeof(ListNode) * (hashmap->table_size));
	return hashmap;
}

static int get_index(HashMap* hm, K key)
{
	assert(hm);
	return (key % (hm->table_size));
}

static ListNode* find(ListNode* list, K key)
{
	ListNode* last = list;
	while (last != NULL)
	{
		if (last->key == key)
			break;
		else
			last = last->next;
	}
	return last;
}

void add(HashMap* hm, K key, V value)
{
	assert(hm);
	int i = get_index(hm, key);
	ListNode* last = find(hm->table[i].next, key);
	if (last == NULL)
	{
		ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
		if (newnode == NULL)
		{
			perror("Creat New Node");
			exit(-1);
		}
		newnode->next = hm->table[i].next;
		hm->table[i].next = newnode;
		newnode->key = key;
		newnode->value = value;
	}
	else
	{
		last->value = value;
	}
}


void remove_by_key(HashMap* hm, K key)
{
	assert(hm);
	int i = get_index(hm, key);
	ListNode* fast, * slow;
	slow = &(hm->table[i]);
	fast = slow->next;
	while (fast != NULL)
	{
		if (fast->key == key)
		{
			break;
		}
		fast = fast->next;
		slow = slow->next;
	}
	if (fast == NULL)
	{
		perror("The key hasn't stored in HashMap");
		exit(-1);
	}
	else
	{
		slow->next = fast->next;
		free(fast);
		fast = NULL;
	}
}

K_V get(HashMap* hm, K key)
{
	assert(hm);
	int i = get_index(hm, key);
	ListNode* last = find(hm->table[i].next, key);
	if (last == NULL)
	{
		perror("The key hasn't stored in HashMap");
		exit(-1);
	}
	else
	{
		K_V kv = { 0,0 };
		kv.key = last->key;
		kv.value = last->value;
		return kv;
	}
}

void destory(HashMap* hm)
{
	assert(hm);
	for (int i = 0; i < hm->table_size; i++)
	{
		ListNode* tmp = hm->table[i].next;
		ListNode* cur = tmp;
		while (tmp != NULL)
		{
			cur = cur->next;
			free(tmp);
			tmp = cur;
		}
	}
	free(hm->table);
	free(hm);
}
